# -*- encoding: utf-8 -*-
import os,json,time
from datetime import datetime
import sys
import ffmpeg

class recordVideo():
    def __init__(self):
        self.taskParam = {}
    def record_screen(self):
        print('start ffmpeg')

        recording, recordTime = True, 0
        if not os.path.isdir(self.taskParam['file_path']):os.makedirs(self.taskParam['file_path'])

        width = int(self.taskParam['position']['width'])
        height = int(self.taskParam['position']['height'])

        t = time.time()
        fps = 30
        if self.taskParam['allow_record']:
            #Setup for recording windows desktop to mp4 file
            process = (
                        ffmpeg
                        .input(format='gdigrab',framerate=fps,offset_x=0,offset_y=0,filename='desktop',s='{width}x{height}'.format(width=width,height=height))
                        .output(filename=self.taskParam['fileName'],pix_fmt='yuv420p')
                        .overwrite_output()
                        )
            #Launch video recording
            process = process.run_async(pipe_stdin=True)
        while self.taskParam['allow_record'] and recordTime < self.taskParam['recordTime']:
            print(recordTime)
            recordTime = time.time() - t
        #Stop video recording
        process.communicate(str.encode("q"))
        time.sleep(6) 
        # To be sure that the process ends I wait 3 seconds and then terminate de process (wich is more like kill -9)
        process.terminate()
        self.stop()

    def record_screen_by_user(self):
        recording, recordTime = True, 0
        #self.taskParam = param
        if not os.path.isdir(self.taskParam['file_path']): os.makedirs(self.taskParam['file_path'])

        width = int(self.taskParam['position']['width'])
        height = int(self.taskParam['position']['height'])

        fps = 30

        self.process = (
            ffmpeg                                                                                                  
                .input(format='gdigrab', framerate=fps, offset_x=0, offset_y=0, filename='desktop',                 
                       s='{width}x{height}'.format(width=width, height=height))                                     
                .output(filename=self.taskParam['fileName'], pix_fmt='yuv420p',format='h264')
                .overwrite_output()                                                                                 
        )                                                                                                           
        # Launch video recording
        print(type(self.process))
        self.process = self.process.run_async(pipe_stdin=True)


    def compose_file(self):
        print('start compose_file')
        temp_audio = self.taskParam['fileName'].replace('mp4','mp3')
        audio_process = (
                    ffmpeg
                    .input(filename = self.taskParam['audioUrl'],ss=0,t=int(self.taskParam['recordTime']))
                    .output(filename= temp_audio)
                    .overwrite_output()
                    )
        audio_process = audio_process.run_async(pipe_stdin=True)
        time.sleep(4)
        newFileName = self.taskParam['fileName'].replace(self.taskParam['timeStamp'],str(self.taskParam['recordId']))
        input_video =  ffmpeg.input(self.taskParam['fileName'])
        added_audio = ffmpeg.input(temp_audio)

        out = ffmpeg.output(input_video, added_audio, newFileName, vcodec='copy', acodec='aac', strict='experimental',pix_fmt='yuv420p')
        compose_process = out.run_async(pipe_stdin=True)
        time.sleep(10)
        if os.path.exists(self.taskParam['fileName']):
            os.remove(self.taskParam['fileName'])
        self.taskParam['fileName'] = newFileName
        audio_process.terminate()
        compose_process.terminate()
        if os.path.exists(temp_audio):
            os.remove(temp_audio)
        print('end compose_file')

    def stoprecord(self):
        print("stop record")
        #self.taskParam['allow_record'] = False
        # To be sure that the process ends I wait 3 seconds and then terminate de process (wich is more like kill -9)
        #newFileName = self.taskParam['fileName'].replace(self.taskParam['timeStamp'], str(self.taskParam['recordId']))
        #input_video = ffmpeg.input(self.taskParam['fileName'])
        #added_audio = ffmpeg.input(temp_audio)

        #out = ffmpeg.output(input_video, filename=newFileName, strict='experimental',pix_fmt='yuv420p')
        #compose_process = out.run_async(pipe_stdin=True)
        #time.sleep(10)
        self.process.wait()
        self.process.terminate()

        #if os.path.exists(self.taskParam['fileName']):
           #os.remove(self.taskParam['fileName'])
        #self.taskParam['fileName'] = newFileName
        #compose_process.terminate()

    def stop(self):
        print('stop record')
        self.taskParam['allow_record'] = False
        time.sleep(4)
        self.compose_file()


if __name__ == "__main__":
    os.chdir(os.path.split(os.path.realpath(__file__))[0])
    taskjson = {
        "result": "true", 
        "data": {
            "id": "1", 
            "duration": 50, 
            "width": "740", 
            "recordUrl": "Example Domain", 
            "height": "700",
            "audio": "e://python//ayue.mp3",
            "bitrate": "1024k"
        }
    }
    record = recordVideo()
    record.taskParam['position'] = {}
    record.taskParam['position']['width'] = taskjson['data']['width']
    record.taskParam['position']['height'] = taskjson['data']['height']
    record.taskParam['allow_record'] = True
    record.taskParam['recordTime'] = int(taskjson['data']['duration'])
    record.taskParam['file_path'] = os.path.join('recordVideoFile',datetime.now().strftime('%Y%m%d'))
    record.taskParam['timeStamp'] = str(int(time.time() * 1e3))
    record.taskParam['fileName'] = os.path.join(record.taskParam['file_path'],record.taskParam['timeStamp']+".mp4")
    record.taskParam['audioUrl'] = taskjson['data']['audio']
    record.taskParam['bitrate'] = taskjson['data']['bitrate']
    record.taskParam['recordId'] = taskjson['data']['id']
    record.record_screen()